<?php
/**
 * Created by PhpStorm.
 * User: mojie126
 * Date: 2017/7/5 0005
 * Time: 上午 10:50
 */

namespace app\index\controller;


use app\common\mailqueue;
use app\common\qr;
use app\common\verify;
use app\index\model\Users;
use OTPHP\TOTP;
use think\Validate;

class UsersController extends Base
{
	public function index()
	{
		$this->assign("title", "控制面板");
		$info = Users::getUserInfo(session("uid"));
		$keygen = $this->key();
		$totp = new TOTP($info['username'], $keygen);
		$totp->setIssuer(APP_NAME);
		$info['qr'] = qr::qrcode($totp->getProvisioningUri());
		$info['jam'] = $keygen;
		$info['url'] = getWebURL() . "/check/" . $info['extract'];
		$this->assign("u", $info);

		return $this->fetch();
	}

	public function verify2FA($code, $k)
	{
		$info = db("users")->where("uid", session("uid"))->field(["username", "safekey", "2fa", "2fakey"])->find();
		if (empty($info['2fakey'])) {
			$keygen = $k;
		} else {
			$keygen = $info['2fakey'];
		}
		$totp = new TOTP($info['username'], $keygen);
		if ($code == $totp->now()) {
			if ($info['2fa'] == 0) {
				db("users")->where("uid", session("uid"))->update(["2fa" => 1, "2fakey" => $k]);
				jsonReturn(1, "2FA绑定成功", ["twofa" => "已绑定"]);
			} elseif ($info['2fa'] == 1) {
				db("users")->where("uid", session("uid"))->update(["2fa" => 0, "2fakey" => ""]);
				jsonReturn(1, "2FA解绑成功", ["twofa" => "未绑定"]);
			}
		} else {
			jsonReturn(0, "2FA验证码错误");
		}
	}

	public function verifyPassword($uid, $password, $type, $token, $twofa = NULL)
	{
		//输入验证
		$rule = [
			"__token__" => "require|token"
		];
		$msg = [
			"__token__" => "请刷新页面后重试"
		];
		$data = [
			"__token__" => $token
		];
		$validate = new Validate($rule, $msg);
		$check = $validate->check($data);
		if (!$check) {
			jsonReturn(2, $validate->getError());
		}
		//输入验证

		if ($uid != session("uid")) {
			jsonReturn(0, "你是在忽悠我么...？（｡◕ˇ＿ˇ◕｡）");
		}

		$info = db("users")->where("uid", $uid)->field(["passsha", "safekey", "username", "2fa", "2fakey"])->find();
		if ($info['2fa'] == 1) {
			if (!empty($twofa)) {
				$totp = new TOTP($info['username'], $info['2fakey']);
				if ($twofa == $totp->now()) {
					jsonReturn(1);
				} else {
					jsonReturn(0, "动态验证码错误");
				}
			} else {
				jsonReturn(0, "动态验证码不能为空");
			}
		}
		$tmp_pwd = md5(md5($info['safekey'] . $password . $info['username'] . $info['safekey']));
		if ($info['passsha'] == $tmp_pwd) {
			if ($type == 0) {
				$uuid = random(3, 21, $info['safekey'] . $info['username']);
				db("users")->where("uid", $uid)->update(["uuid" => $uuid]);
			} elseif ($type == 1) {
				db("users")->where("uid", $uid)->update([
					"appid" => random(11, 9),
					"appkey" => random(13, 21)
				]);
			} elseif ($type == 2) {
				db("users")->where("uid", $uid)->update(["extract" => random(15, 13)]);
			} elseif ($type == 3) {
				//输入验证
				$rule = [
					"password1|密码" => "require|length:6,32",
					"password2" => "require|confirm:password1",
				];
				$msg = [
					"password1" => "密码长度必须在 6~32 个字符之间",
					"password2" => "两次密码不一致",
				];
				$data = [
					"password1" => input("password1"),
					"password2" => input("password2")
				];
				$validate = new Validate($rule, $msg);
				$check = $validate->check($data);
				if (!$check) {
					jsonReturn(2, $validate->getError());
				}
				//输入验证
				$reset_pwd = md5(md5($info['safekey'] . input("password1") . $info['username'] . $info['safekey']));
				db("users")->where("uid", $uid)->update(["passsha" => $reset_pwd]);
			}
			jsonReturn(1);
		} else {
			jsonReturn(0, "密码错误");
		}
	}

	public function sendInvite()
	{
		$this->assign("title", "发送邀请");
		$info = db("invite")->where("uid", session("uid"))->order("id", "DESC")->select();
		$this->assign("info", $info);

		return $this->fetch();
	}

	public function doSendInvite($email)
	{
		/*
		 * 检查该邮箱是否已经注册过
		 * 检查帐号是否有邀请可发，临时+永久
		 * 生成邀请码并扣除该帐号邀请数，优先使用临时邀请
		 * 将生成的邀请码封装进jwt后发送给指定邮箱并返回发送结果
		 */
		$check1 = db("invite")->where("email", $email)->count("uid");
		$check2 = db("users")->where("email", $email)->count("uid");
		if (!empty($check1)) {
			jsonReturn(0, "该邮箱已经注册");
		} elseif (!empty($check2)) {
			jsonReturn(0, "该邮箱已经注册");
		}
		$info = db("users")->where("uid", session("uid"))->field(["shortinv", "longinv", "uid", "username"])->find();
		$invite_count = $info['shortinv'] + $info['longinv'];
		if ($invite_count > 0) {
			$invite_code = random(5, 21);
			$insert = [
				"uid" => $info['uid'],
				"addtime" => nowtime(),
				"invitecode" => $invite_code,
				"email" => $email
			];
			db()->transaction(function () use ($insert, $info) {
				db("invite")->insert($insert);
				if ($info['shortinv'] > 0) {
					db("users")->where("uid", $info['uid'])->dec("shortinv")->update();
				} elseif ($info['longinv'] > 0) {
					db("users")->where("uid", $info['uid'])->dec("longinv")->update();
				}
			});
			$exp = 86400 * 7;
			$jwt = verify::encode($invite_code, $exp);
			//可以自己修改邮件内容，支持HTML ↓
			$msg = "<p>请在7天内点击链接进行邀请注册：<a href=" . getWebURL() . url("/index/signup/index", ["verify" => $jwt]) . " target='_blank'>点我点我</a></p><p>邀请人：$info[username]</p><p><a target='_blank' href=" . getWebURL() . ">" . APP_NAME . "</a></p>";
			//可以自己修改邮件内容，支持HTML ↑
			$res = mailqueue::mailqueue($email, "$info[username]的邀请注册 - " . APP_NAME, $msg);
			if ($res) {
				jsonReturn(1, "邮件发送成功，请注意查收（包括垃圾箱）", ["url" => $msg]);
			} else {
				jsonReturn(0, "邮件发送失败，请稍后再试", ["url" => $msg]);
			}
		} else {
			jsonReturn(0, "邀请数量不足");
		}
	}
}